package pl.lodz.p.beans;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import pl.lodz.p.model.Doctor;
import pl.lodz.p.model.Patient;
import pl.lodz.p.model.Schedule;
import pl.lodz.p.model.User;
import pl.lodz.p.model.WorkingDay;
import pl.lodz.p.model.enums.AccountType;
import pl.lodz.p.model.enums.DayOfTheWeek;
import pl.lodz.p.model.enums.EnumBean;
import pl.lodz.p.model.enums.Gender;
import pl.lodz.p.model.enums.Specialization;
import pl.lodz.p.services.DoctorService;
import pl.lodz.p.services.DoctorServiceImpl;
import pl.lodz.p.services.PatientService;
import pl.lodz.p.services.PatientServiceImpl;
import pl.lodz.p.services.UserService;
import pl.lodz.p.services.UserServiceImpl;
import pl.lodz.p.services.VisitService;
import pl.lodz.p.services.VisitServiceImpl;

public class ManagerManagedBean implements Serializable{

	private static final long serialVersionUID = 4902488308323752856L;

	private DoctorService doctorService = new DoctorServiceImpl();

	private VisitService visitService = new VisitServiceImpl();
	
	private static Logger log = Logger.getLogger(ManagerManagedBean.class);

	private String pesel;
	
	private String firstName;
	
	private String lastName;
	
	private AccountType accType;
	
	private Boolean active = Boolean.TRUE;
	
	private Specialization spec;
	
	private Gender gender;
	
	private List<Doctor> filtered;
	
	private List<User> filteredUser;
	private List<User> filteredValue;
	private List<Patient> filteredPatients;
	
	private User chosenUser;
	
	private Doctor chosen;
	
	private UserService userService = new UserServiceImpl();
	
	private Date scheduleFromDate;
	private Date scheduleToDate;
	private Date scheduleStartHour;
	private Date scheduleToHour;
	
	private Date minDate = new Date();
	
	private PatientService patientService = new PatientServiceImpl();
	
	private List<Patient> patients;
	
	private List<String> chosenDays = new ArrayList<String>();
	
	private boolean showSettings = false;
	
	public String filterPatients() {
		setPatients(patientService.findByMany(firstName, lastName, pesel, gender));
		return "";
	}
	
	public String findAllPatients() {
		setPatients(patientService.findAll());
		return "";
	}
	
	public String show(){
		return "manageDoctorSchedule?faces-redirect=true";
	}
	
	public String edit(){
		return "editDoctor?faces-redirect=true";
	}

	public String filtering(){
		filtered = findDoctorsByFilter();
		return "success";
	}

	public String filteringUsers(){
		filteredUser = findUsersByFilter();
		return "success";
	}
	
	public String getAll(){
		filtered = doctorService.findAll();
		return "success";
	}
	
	public String getAllUsers(){
		filteredUser = userService.findAll();
		return "success";
	}
	
	public String reset(){
		pesel = "";
		firstName = "";
		lastName = "";
		gender = null;
		spec = null;
		if (filtered != null){
			filtered.clear();
		}	
		return "";
	}
	
	public String generateSchedules(){
		Schedule schedule = doctorService.findLastSchedule(chosen);
		Date lastScheduleDate = new Date();
		if (schedule != null){
			lastScheduleDate = schedule.getDateStart();
		}
		lastScheduleDate.setHours(0);
		lastScheduleDate.setMinutes(0);
		lastScheduleDate.setSeconds(0);
		Calendar c = Calendar.getInstance();
		c.setTime(lastScheduleDate);
		c.add(Calendar.DAY_OF_YEAR, 1);
		doctorService.addWorkDays(chosen, c.getTime());
		return "";
	}
	
	public List<Doctor> findDoctorsByFilter(){
		return doctorService.findByMany(firstName, lastName, pesel, spec, gender);
	}
	
	public List<User> findUsersByFilter(){
		return userService.findByMany(firstName, lastName, pesel, active, gender, accType);
	}
	
	public List<Doctor> getAllDoctor(){
		return doctorService.findAll();
	}
	
	public VisitService getVisitService() {
		return visitService;
	}
	
	public void setVisitService(VisitService visitService) {
		this.visitService = visitService;
	}

	public List<Doctor> getFiltered() {
		return filtered;
	}

	public void setFiltered(List<Doctor> filtered) {
		this.filtered = filtered;
	}

	public String getPesel() {
		return pesel;
	}

	public void setPesel(String pesel) {
		this.pesel = pesel;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public Specialization getSpec() {
		return spec;
	}

	public void setSpec(Specialization spec) {
		this.spec = spec;
	}

	public Gender getGender() {
		return gender;
	}

	public void setGender(Gender gender) {
		this.gender = gender;
	}

	public Doctor getChosen() {
		return chosen;
	}

	public void setChosen(Doctor chosen) {
		this.chosen = chosen;
	}

	public Date getScheduleFromDate() {
		return scheduleFromDate;
	}

	public void setScheduleFromDate(Date scheduleFromDate) {
		this.scheduleFromDate = scheduleFromDate;
	}

	public Date getScheduleToDate() {
		return scheduleToDate;
	}

	public void setScheduleToDate(Date scheduleToDate) {
		this.scheduleToDate = scheduleToDate;
	}

	public Date getScheduleStartHour() {
		return scheduleStartHour;
	}

	public void setScheduleStartHour(Date scheduleStartHour) {
		this.scheduleStartHour = scheduleStartHour;
	}

	public Date getScheduleToHour() {
		return scheduleToHour;
	}

	public void setScheduleToHour(Date scheduleToHour) {
		this.scheduleToHour = scheduleToHour;
	}

	public Date getMinDate() {
		return minDate;
	}

	public void setMinDate(Date minDate) {
		this.minDate = minDate;
	}

	/**
	 * @return the accType
	 */
	public AccountType getAccType() {
		return accType;
	}

	/**
	 * @param accType the accType to set
	 */
	public void setAccType(AccountType accType) {
		this.accType = accType;
	}

	/**
	 * @return the active
	 */
	public boolean getActive() {
		return active.booleanValue();
	}

	/**
	 * @param active the active to set
	 */
	public void setActive(boolean active) {
		this.active = new Boolean(active);
	}

	/**
	 * @return the filteredUser
	 */
	public List<User> getFilteredUser() {
		return filteredUser;
	}

	/**
	 * @param filteredUser the filteredUser to set
	 */
	public void setFilteredUser(List<User> filteredUser) {
		this.filteredUser = filteredUser;
	}

	/**
	 * @return the chosenUser
	 */
	public User getChosenUser() {
		return chosenUser;
	}

	/**
	 * @param chosenUser the chosenUser to set
	 */
	public void setChosenUser(User chosenUser) {
		this.chosenUser = chosenUser;
	}

	public List<User> getFilteredValue() {
		return filteredValue;
	}

	public void setFilteredValue(List<User> filteredValue) {
		this.filteredValue = filteredValue;
	}

	public String loginAsUser(){
		LoginBean bean = (LoginBean) pl.lodz.p.beans.utils.Util.getSession().getAttribute("loginBean");
		if (bean.getLoginPersonel() == null){
			bean.setLoginPersonel(bean.getLoginUser());
			bean.setLoginUser(chosenUser);
			bean.setLoginAsOther(new Boolean(true));
		}
		return "";
	}
	
	public boolean isLoginAsAvailable() {
		LoginBean bean = (LoginBean) pl.lodz.p.beans.utils.Util.getSession().getAttribute("loginBean");
		ManagerManagedBean mmb = (ManagerManagedBean) pl.lodz.p.beans.utils.Util.getSession().getAttribute("managerMB");
		User u = mmb.getChosenUser();
		if (bean.getLoginPersonel() == null){
			return true;
		}
		return false;
	}
		
	public String activate(){
		chosenUser.setActive(true);
		userService.saveUser(chosenUser);
		return "";
	}

	public String deactivate(){
		chosenUser.setActive(false);
		userService.saveUser(chosenUser);
		return "";
	}

	/**
	 * @return the patients
	 */
	public List<Patient> getPatients() {
		return patients;
	}

	/**
	 * @param patients the patients to set
	 */
	public void setPatients(List<Patient> patients) {
		this.patients = patients;
	}

	public List<String> getChosenDays() {
		return chosenDays;
	}

	public void setChosenDays(List<String> chosenDays) {
		this.chosenDays = chosenDays;
	}

	public boolean isShowSettings() {
		return showSettings;
	}

	public void setShowSettings(boolean showSettings) {
		this.showSettings = showSettings;
	}
	
	public String chooseDays(){
		for (String day : chosenDays) {
			WorkingDay workingDay = new WorkingDay();
			workingDay.setDayOfTheWeek(DayOfTheWeek.valueOf(day));
			workingDay.setStartHour(7);
			workingDay.setEndHour(21);
			workingDay.setDoctor(chosen);
			chosen.getWorkingDays().add(workingDay);
		}
		showSettings = true;
		return "";
	}
	
	public String saveWorkingHours(){
		doctorService.save(chosen);
		showSettings = false;
		return "manageDoctorSchedule?faces-redirect=true";
	}
	
	public String clearWorkingDays(){
		chosen.getWorkingDays().clear();
		showSettings = true;
		chosenDays.clear();
		return "";
	}
	
	public String addSchedule(){
		if (chosen != null){
			if (chosen.getWorkingDays() == null){
				chosen.setWorkingDays(new HashSet<WorkingDay>());
			}
			if (chosen.getWorkingDays().size() != 7){
				Set<WorkingDay> days = new HashSet<WorkingDay>();
				for (DayOfTheWeek day : new EnumBean().getDayOfTheWeek()) {
					WorkingDay workingDay = new WorkingDay();
					workingDay.setDayOfTheWeek(day);
					workingDay.setStartHour(7);
					workingDay.setEndHour(21);
					workingDay.setDoctor(chosen);
					days.add(workingDay);
				}
				chosen.setWorkingDays(days);
			}
		}
		return "addSchedule?faces-redirect=true";
	}

	public List<Patient> getFilteredPatients() {
		return filteredPatients;
	}

	public void setFilteredPatients(List<Patient> filteredPatients) {
		this.filteredPatients = filteredPatients;
	}
}
